﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Linq;



public class VSEdmxFile
{

    public string FileName { get { return Path.GetFileName(FileLoc); } }

    private string FileLoc { get; set; }

    private XElement FileXML { get; set; }

    public List<EntitySet> Entities { get; set; }

    public List<NavigateDef> Navigates { get; set; }

    private XNamespace XMLNS { get; set; }

    public bool AuthEnabled { get; set; }

    public VSEdmxFile()
    {
        Entities = new List<EntitySet>();
        Navigates = new List<NavigateDef>();
    }

    public VSEdmxFile(string file)
    {
        FileLoc = file;
        FileXML = XElement.Load(file);
        Entities = new List<EntitySet>();
        Navigates = new List<NavigateDef>();
        Load();
    }

    public string GetEntityContainer()
    {


        return FileXML.Descendants(XMLNS + "EntityContainer").FirstOrDefault().Attribute("Name").Value;




    }

    public void Load()
    {
        // determine NS
        XNamespace ns2 = "http://schemas.microsoft.com/ado/2006/04/edm/ssdl";
        if (FileXML.Descendants((XNamespace)"http://schemas.microsoft.com/ado/2008/09/edm" + "EntityContainer").Count() > 0)
        {
            XMLNS = "http://schemas.microsoft.com/ado/2008/09/edm";
            ns2 = "http://schemas.microsoft.com/ado/2009/02/edm/ssdl";

        }
        else if (FileXML.Descendants((XNamespace)"http://schemas.microsoft.com/ado/2006/04/edm" + "EntityContainer").Count() > 0)
        {
            XMLNS = "http://schemas.microsoft.com/ado/2006/04/edm";
            ns2 = "http://schemas.microsoft.com/ado/2006/04/edm/ssdl";

        }


        // EntityType
        XNamespace ns = XMLNS;

        var entities = FileXML.Descendants(ns + "EntitySet");
        foreach (var e in entities)
        {
            if (this.Entities.Count(c => c.SetName == e.Attribute("Name").Value) == 0)
            {
                // try load from secfile
                var esfileloc = new Uri(Path.Combine(Path.GetDirectoryName(FileLoc), e.Attribute("Name").Value + ".seccfg")).AbsolutePath.Replace("%20", " ");

                if (File.Exists(esfileloc))
                {
                    var esfile = XmlFileProvider.OpenXMLObjectFile<EntitySet>(esfileloc);

                    esfile.SetName = e.Attribute("Name").Value;
                    esfile.ObjectName = e.Attribute("EntityType").Value.Split('.').LastOrDefault();

                    this.Entities.Add(esfile);

                }
                else
                {

                    this.Entities.Add(new EntitySet()
                    {
                        SetName = e.Attribute("Name").Value,
                        ObjectName = e.Attribute("EntityType").Value.Split('.').LastOrDefault()
                    });
                }
            }
        }


        ////NavigationProperty

        //if (this.FW == FrameworkDefs.Framework4)
        //{
        //   
        //}
        //else if (this.FW == FrameworkDefs.Framework35)
        //{
        //    
        //}



        //var navigates = FileXML.Descendants(ns2 + "Association");
        //foreach (var n in navigates)
        //{
        //    this.Navigates.Add(new NavigateDef()
        //    {
        //        FromSet = Entities[n.Descendants(ns2 + "Principal").First().Attribute("Role").Value],
        //        ToSet = Entities[n.Descendants(ns2 + "Dependent").First().Attribute("Role").Value],
        //    });
        //}

        //<Principal Role="licensetypes">
        //     <PropertyRef Name="licensetypeid" />
        //   </Principal>
        //   <Dependent Role="licenses">
        //     <PropertyRef Name="licensetypeid" />
        //   </Dependent>

    }


    public override string ToString()
    {
        return GetEntityContainer();
    }


}

public class EntitySet
{
    public string SetName { get; set; }
    public string ObjectName { get; set; }
    public List<string> Read { get; set; }
    public List<string> Write { get; set; }
    public List<string> Delete { get; set; }
    public List<string> All { get; set; }

    public EntitySet()
    {
        Read = new List<string>();
        Write = new List<string>();
        Delete = new List<string>();
        All = new List<string>();
    }

    public bool HasSecurity()
    {
        int i = 0;
        i += Read.Count;
        i += Write.Count;
        i += Delete.Count;
        i += All.Count;
        if (i > 0) return true;
        else return false;

    }


    public string GetReadGroups()
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("[RequiresRole(");
        foreach (var item in All)
        {
            sb.Append(" \"" + item + "\",");
        }

        foreach (var item in Read)
        {
            sb.Append(" \"" + item + "\",");
        }

        return sb.ToString().TrimEnd(',') + " )]";
    }

    public string GetWriteGroups()
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("[RequiresRole(");
        foreach (var item in All)
        {
            sb.Append(" \"" + item + "\",");
        }

        foreach (var item in Write)
        {
            sb.Append(" \"" + item + "\",");
        }

        return sb.ToString().TrimEnd(',') + ")]";
    }

    public string GetDeleteGroups()
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("[RequiresRole(");
        foreach (var item in All)
        {
            sb.Append(" \"" + item + "\",");
        }

        foreach (var item in Delete)
        {
            sb.Append(" \"" + item + "\",");
        }

        return sb.ToString().TrimEnd(',') + ")]";
    }


    public string GetCreateGroups()
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("[RequiresRole(");
        foreach (var item in All)
        {
            sb.Append(" \"" + item + "\",");
        }

        foreach (var item in Write)
        {
            sb.Append(" \"" + item + "\",");
        }

        return sb.ToString().TrimEnd(',') + ")]";
    }

    public string GetEntityCode(string datacontext)
    {
        // secgroups

        TemplateEngine wcfroot = null;
        if (HasSecurity())
        {
            wcfroot = new TemplateEngine(File.ReadAllText(@"Templates\WCFDataMethods.txt"));

            // [RequiresRole("Registered Users", "Admins")]
            wcfroot.SetVar("secgroupsread", GetReadGroups());
            wcfroot.SetVar("secgroupsdel", GetDeleteGroups());
            wcfroot.SetVar("secgroupswrite", GetWriteGroups());
            wcfroot.SetVar("secgroupscreate", GetCreateGroups());

        }
        else
        {
            wcfroot = new TemplateEngine(File.ReadAllText(@"Templates\WCFDataMethodsOpen.txt"));
        }



        wcfroot.SetVar("obj", ObjectName);
        wcfroot.SetVar("objplural", SetName);
        wcfroot.SetVar("datacontext", datacontext);
        return wcfroot.ToString();
    }

    public string GetSLCode()
    {
        TemplateEngine wcfroot = null;

        wcfroot = new TemplateEngine(File.ReadAllText(@"Templates\AppCoreNoAuth.txt"));

        wcfroot.SetVar("objset", SetName);
        wcfroot.SetVar("obj", ObjectName);
        return wcfroot.ToString();

    }


    public override string ToString()
    {
        return SetName;// +" [" + ObjectName + "]"; 
    }
}

public class NavigateDef
{
    public EntitySet FromSet { get; set; }
    public EntitySet ToSet { get; set; }


}







